home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- Project : MacPerl - Real Perl Application
- File : MPHelp.c - Various helpful functions
- Author : Matthias Neeracher
- Language : MPW C
-
- $Log: MPHelp.c,v $
- Revision 1.1 1994/02/27 23:01:10 neeri
- Initial revision
-
- Revision 0.2 1993/09/08 00:00:00 neeri
- Corrected some misunderstandings of dbm
-
- Revision 0.1 1993/08/17 00:00:00 neeri
- Use Application directory
-
- *********************************************************************/
-
- #ifndef RUNTIME
-
- #include "MPHelp.h"
- #include "MPConsole.h"
-
- #include <Balloons.h>
- #include <ToolUtils.h>
- #include <TFileSpec.h>
- #include <ndbm.h>
- #include <ctype.h>
- #include <PLStringFuncs.h>
- #include <Folders.h>
- #include <fcntl.h>
- #include <ioctl.h>
- #include <stdio.h>
- #include <string.h>
-
- #include "icemalloc.h"
-
- static DBM * OperatorBalloons = nil;
- static char BalloonState = '?';
- static FSSpec BalloonPath;
- static _mem_pool_ptr HelpMem;
- static int SavePoolID;
-
- Boolean HasBalloons()
- {
- CInfoPBRec info;
-
- if (!HelpMem)
- if (!(HelpMem = new_malloc_pool(4711, (16 * 1024))))
- return false;
-
- SavePoolID = _default_mem_pool->id;
- set_default_pool(4711);
-
- if (OperatorBalloons)
- return true;
-
- switch (BalloonState) {
- case '+':
- if (OperatorBalloons = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
- return true;
- case '?':
- BalloonState = '+';
- BalloonPath.vRefNum = gAppVol;
- BalloonPath.parID = gAppDir;
- PLstrcpy(BalloonPath.name, "\pMacPerl Help");
-
- if (!FSpCatInfo(&BalloonPath, &info))
- if (OperatorBalloons = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
- return true;
-
- if (!FindFolder(
- kOnSystemDisk,
- kPreferencesFolderType,
- false,
- &BalloonPath.vRefNum,
- &BalloonPath.parID)
- && !FSpCatInfo(&BalloonPath, &info)
- )
- if (OperatorBalloons = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
- return true;
-
- BalloonState = '-';
- case '-':
- set_default_pool(SavePoolID);
- return false;
- }
- }
-
- void HideBalloons()
- {
- dbm_close(OperatorBalloons);
-
- OperatorBalloons = nil;
-
- set_default_pool(SavePoolID);
- }
-
- void DoHelp(WindowPtr win, DPtr doc, Point pt, Boolean inText)
- {
- short index;
- short last;
- short length;
- datum key;
- datum data;
- Ptr txt;
- Rect r;
- HMMessageRecord help;
-
- if (!HMGetBalloons() || HMIsBalloon())
- return;
-
- if (inText) {
- index = TEGetOffset(pt, doc->theText);
- length= (*doc->theText)->teLength;
-
- if (index <= 0 || index >= length)
- return;
-
- txt = *(*doc->theText)->hText;
-
- if (islower(txt[index])) {
- for (last = index+1; last < (*doc->theText)->teLength; last++)
- if (islower(txt[last]))
- continue;
- else if (isalnum(txt[last]))
- return;
- else
- break;
-
- while (index-- > 0)
- if (islower(txt[index]))
- continue;
- else if (isalnum(txt[index]))
- return;
- else
- break;
-
- ++index;
- } else {
- last = index+1;
- }
-
- if (!HasBalloons())
- return;
-
- HLock((*doc->theText)->hText);
- key.dptr = *(*doc->theText)->hText + index;
- key.dsize = last - index;
- data = dbm_fetch(OperatorBalloons, key);
- HUnlock((*doc->theText)->hText);
-
- HideBalloons();
-
- if (!data.dptr)
- return;
-
- help.hmmHelpType = kHMStringItem;
- help.u.hmmString[0] = data.dsize;
- memcpy(&help.u.hmmString+1, data.dptr, data.dsize);
-
- LocalToGlobal(&pt);
- *(Point *) &r.top = pt;
- *(Point *) &r.bottom = pt;
- InsetRect(&r, -5, -5);
-
- HMShowBalloon(&help, pt, &r, nil, 0, 0, kHMRegularWindow);
- } else {
- r = win->portRect;
-
- r.right = 30;
- r.top = r.bottom-15;
-
- if (PtInRect(pt, &r)) {
- help.hmmHelpType = kHMStringItem;
-
- switch (doc->lastState) {
- case stateDocument+stateRdWr:
- index = 1;
- break;
- case stateDocument+stateRdOnly:
- index = 2;
- break;
- case stateConsole+stateRdWr:
- index = 3;
- break;
- case stateConsole+stateRdOnly:
- index = 4;
- break;
- case stateConsole+stateBlocked:
- index = 5;
- break;
- default:
- return;
- }
- GetIndString(help.u.hmmString, 256, index);
-
- LocalToGlobal((Point *) &r.top);
- LocalToGlobal((Point *) &r.bottom);
- LocalToGlobal(&pt);
-
- HMShowBalloon(&help, pt, &r, nil, 0, 0, kHMRegularWindow);
- }
- }
- }
-
- typedef struct {
- long start;
- long end;
- } HelpOffsets;
-
- void Explain(DPtr doc)
- {
- datum key;
- datum data;
- FILE * help;
- HelpOffsets offsets;
- Handle txt;
- char * text;
- short pos;
-
- if (!HasBalloons())
- return;
-
- if (doc) {
- TEHandle te;
-
- te = doc->theText;
-
- if (pos = (*te)->selEnd - (*te)->selStart) {
- HLock((*te)->hText);
- PtrToHand(*(*te)->hText + (*te)->selStart - 1, &txt, pos + 2);
- HUnlock((*te)->hText);
- }
- } else
- pos = 0;
-
- if (!pos) {
- pos = 12;
- PtrToHand("xMacPerl…Help", &txt, pos + 2);
- }
-
- (*txt)[0] = 0;
- (*txt)[pos + 1] = 0;
-
- HLock(txt);
- key.dptr = *txt;
- key.dsize = pos + 1;
- data = dbm_fetch(OperatorBalloons, key);
-
- if (!data.dptr) {
- SysBeep(0);
-
- DisposeHandle(txt);
- HideBalloons();
- return;
- }
-
- help = fopen("Dev:Console:Perl Help", "a");
-
- fprintf(help, "\n------------- %s ---------------\n\n", *txt+1);
-
- DisposeHandle(txt);
-
- memcpy(&offsets, data.dptr, sizeof(HelpOffsets));
- txt = NewHandle(offsets.end - offsets.start + 1);
- HLock(txt);
-
- lseek(OperatorBalloons->fd(OperatorBalloons), offsets.start, 0);
- (*txt)[read(OperatorBalloons->fd(OperatorBalloons), *txt, offsets.end - offsets.start)] = 0;
-
- HideBalloons();
-
- for (pos = 0, text = *txt; *text; ) {
- if (!pos && *text == 'æ') {
- if (text[1] == 'C' && isspace(text[2])) {
- for (text += 3; isspace(*text); ++text);
-
- goto nextchar;
- } else if (text[1] == 'K' && text[2] == 'L' && isspace(text[3])) {
- for (text += 3; isspace(*text); ++text);
-
- for (pos = 0;;++text)
- switch (*text) {
- case 'æ':
- if (pos) {
- putc(*text, help);
- ++pos;
- break;
- } else {
- putc('\n', help);
- pos = 0;
-
- goto nextchar;
- }
- case 0:
- if (pos)
- putc('\n', help);
- putc('\n', help);
-
- goto nextchar;
- case '\n':
- if (text[1] == '\n' || !pos || pos >= 30) {
- putc('\n', help);
- pos = 0;
- } else
- while (pos < 30) {
- putc(' ', help);
- ++pos;
- }
- break;
- case ' ':
- case '\t':
- break;
- default:
- putc(*text, help);
- ++pos;
- break;
- }
- } else if (text[1] == 'D' && text[2] == 'T' && isspace(text[3]))
- for (text += 3; *text; )
- if (*text++ == '\n') {
- pos = 0;
-
- goto nextchar;
- }
- }
- putc(*text, help);
-
- pos = (*text++ != '\n');
- nextchar:
- ;
- }
-
- ioctl(fileno(help), WIOSELECT, NULL);
-
- fclose(help);
- DisposeHandle(txt);
- }
-
- #endif